#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <string>
#include <unistd.h>
#include <pthread.h>
#include <memory>
#include <vector>
#include "Thread.hpp"
#include "Mutex.hpp"
using namespace std;

class ThreadData
{
public:
    ThreadData(const std::string threadname, pthread_mutex_t *mutex_p)
        : threadname_(threadname), mutex_p_(mutex_p)
    {
    }
    ~ThreadData() {}

public:
    std::string threadname_;
    pthread_mutex_t *mutex_p_;
};

// 多个线程交叉运行，即让调度器频繁地发生线程调度与切换
// 线程一般在时间片结束，来了更高级别的线程，线程等待的时候发生
// 线程等待：当从内核态返回用户态的实施，线程要对调度状态监测，如果可以，就发生切换
// 检测工作是由OS来做的，但是线程共享地址空间，执行OS的代码本来就是在线程上下文执行，3--4G是内核代码
// 当线程检测，只不过执行OS代码，实际上就是OS在检测
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
int tickets = 100; // 共享资源
void *get_ticket(void *args)
{
    std::string name = static_cast<const char *>(args);
    while (true)
    {
        {//加上匿名区域，限定生命周期
            LockGuard lockguard(&lock);//RAII风格
        
            if (tickets > 0)
            {
                usleep(1111); // 引起线程阻塞，挂起，切换其他线程
                cout << name << "正在抢票 : " << tickets << endl;
                tickets--;
            }
            else
            {
                break;
            }
        }
        usleep(1000);
    }
    return nullptr;
}

int main()
{
    std::unique_ptr<Thread> thread1(new Thread(get_ticket, (void *)"User1", 1));
    std::unique_ptr<Thread> thread2(new Thread(get_ticket, (void *)"User2", 2));
    std::unique_ptr<Thread> thread3(new Thread(get_ticket, (void *)"User3", 3));
    std::unique_ptr<Thread> thread4(new Thread(get_ticket, (void *)"User4", 4));

    thread1->join();
    thread2->join();
    thread3->join();
    thread4->join();
    return 0;
}

// int tickets = 500; // 共享资源
// void *get_ticket(void *args)
// {
//     ThreadData *td = static_cast<ThreadData *>(args);
//     while (true)
//     {
//         pthread_mutex_lock(td->mutex_p_);
//         /* */ if (tickets > 0)
//         /*临*/ {
//         /*  */      usleep(1111); // 引起线程阻塞，挂起，切换其他线程
//         /*界*/      cout << td->threadname_ << "正在抢票 : " << tickets << endl;
//         /*  */      tickets--;
//         /*区*/      pthread_mutex_unlock(td->mutex_p_);
//                 }
//         else
//         {
//             pthread_mutex_unlock(td->mutex_p_);
//             break;
//         }
//         usleep(1000);//休息一会，让别的线程申请锁
//     }

//     return nullptr;
// }
// int main()
// {
// #define NUM 4
//     pthread_mutex_t lock;
//     pthread_mutex_init(&lock, nullptr);
//     vector<pthread_t> tids(NUM);
//     for (int i = 0; i < NUM; ++i)
//     {
//         char buffer[1024];
//         snprintf(buffer, sizeof buffer, "thread %d", i + 1);
//         ThreadData *td = new ThreadData(buffer, &lock);
//         pthread_create(&tids[i], nullptr, get_ticket, td);
//     }
//     for(const auto& tid:tids)
//     {
//         pthread_join(tid,nullptr);
//     }
//     return 0;
// }